package com.zxhhyj.storm.schema

import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.format
import kotlinx.datetime.format.DateTimeFormat

open class Table<T>(val tableName: String) {

    internal val columns = mutableListOf<Column<T, *>>()

    fun <V> ColumnBuilder<T, V>.bindTo(selector: ColumnBindingProperty<T, V>): Column<T, V> {
        val column = Column.RowBinding(
            fieldName = fieldName,
            kotlinType = kotlinType,
            dataType = dataType,
            isPrimaryKey = isPrimaryKey,
            isAutoincrement = isAutoincrement,
            isNull = isNull,
            isUnique = isUnique,
            converter = converter,
            defaultProvider = defaultProvider,
            selector = selector,
        )
        columns.remove(this)
        columns.add(column)
        return column
    }

    fun int(fieldName: String, fieldLength: Int? = null): ColumnBuilder<T, Int> {
        val column = ColumnBuilder<T, Int>(fieldName, DataType.INTEGER)
        columns.add(column)
        return column
    }

    fun varchar(fieldName: String): ColumnBuilder<T, String> {
        val column = ColumnBuilder<T, String>(fieldName, DataType.TEXT)
        columns.add(column)
        return column
    }

    fun long(fieldName: String): ColumnBuilder<T, Long> {
        val column = ColumnBuilder<T, Long>(fieldName, DataType.INTEGER)
        columns.add(column)
        return column
    }

    fun real(fieldName: String): ColumnBuilder<T, Float> {
        val column = ColumnBuilder<T, Float>(fieldName, DataType.REAL)
        columns.add(column)
        return column
    }

    fun blob(fieldName: String): ColumnBuilder<T, ByteArray> {
        val column = ColumnBuilder<T, ByteArray>(fieldName, DataType.BLOB)
        columns.add(column)
        return column
    }

    fun boolean(fieldName: String): ColumnBuilder<T, Boolean> {
        return int(fieldName).transform({ it == 1 }, { if (it) 1 else 0 })
    }

    fun date(
        fieldName: String,
        format: DateTimeFormat<LocalDate> = LocalDate.Formats.ISO
    ): ColumnBuilder<T, LocalDate> {
        return varchar(fieldName).transform({ LocalDate.parse(it, format) }, { it.format(format) })
    }

    fun datetime(
        fieldName: String,
        format: DateTimeFormat<LocalDateTime> = LocalDateTime.Formats.ISO
    ): ColumnBuilder<T, LocalDateTime> {
        return varchar(fieldName).transform({ LocalDateTime.parse(it, format) }, { it.format(format) })
    }

    fun enum(fieldName: String) {

    }
}